from commons.database import Database, Base
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from typing import Dict, List, Optional, Type, Any
from .database import Database, Session


class APIBase:
    """通用API请求处理基类，提供基础的CRUD操作接口"""
    def __init__(self, app: FastAPI, model: Type[Base]):
        # 从模型提取说明文字
        self.model_description = model.__doc__ or f"{model.__name__}资源"
        self.model_name = model.__name__
        """初始化API基类

        Args:
            app: FastAPI应用实例
            model: SQLAlchemy模型类
        """
        self.app = app
        self.model = model
        self.db_session = Database.get_db
        self.setup_routes()

    def setup_routes(self):
        """设置API路由"""
        # 获取单个资源
        @self.app.get(f"/{self.model.__tablename__}/{{item_id}}", response_model=Dict[str, Any],
              summary=f"获取{self.model_name}详情",
              description=f"根据ID查询{self.model_description}的详细信息")
        def get_item(item_id: int, db: Session = Depends(self.db_session)):
            item = db.query(self.model).filter(self.model.id == item_id).first()
            if not item:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail=f"{self.model.__name__} with id {item_id} not found"
                )
            return {k: v for k, v in item.__dict__.items() if k != '_sa_instance_state'}

        # 获取所有资源
        @self.app.get(f"/{self.model.__tablename__}", response_model=List[Dict[str, Any]],
              summary=f"获取{self.model_name}列表",
              description=f"查询所有{self.model_description}的列表信息")
        def get_items(db: Session = Depends(self.db_session)):
            items = db.query(self.model).all()
            return [{k: v for k, v in item.__dict__.items() if k != '_sa_instance_state'} for item in items]

        # 创建资源
        @self.app.post(f"/{self.model.__tablename__}", response_model=Dict[str, Any], status_code=status.HTTP_201_CREATED,
               summary=f"创建{self.model_name}",
               description=f"创建新的{self.model_description}记录")
        def create_item(item_data: Dict[str, Any], db: Session = Depends(self.db_session)):
            try:
                db_item = self.model(**item_data)
                db.add(db_item)
                db.commit()
                db.refresh(db_item)
                return {k: v for k, v in db_item.__dict__.items() if k != '_sa_instance_state'}
            except Exception as e:
                db.rollback()
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"Error creating {self.model.__name__}: {str(e)}"
                )

        # 更新资源
        @self.app.put(f"/{self.model.__tablename__}/{{item_id}}", response_model=Dict[str, Any],
              summary=f"更新{self.model_name}",
              description=f"根据ID更新{self.model_description}的信息")
        def update_item(item_id: int, item_data: Dict[str, Any], db: Session = Depends(self.db_session)):
            db_item = db.query(self.model).filter(self.model.id == item_id).first()
            if not db_item:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail=f"{self.model.__name__} with id {item_id} not found"
                )
            try:
                for key, value in item_data.items():
                    setattr(db_item, key, value)
                db.commit()
                db.refresh(db_item)
                return {k: v for k, v in db_item.__dict__.items() if k != '_sa_instance_state'}
            except Exception as e:
                db.rollback()
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"Error updating {self.model.__name__}: {str(e)}"
                )

        # 删除资源
        @self.app.delete(f"/{self.model.__tablename__}/{{item_id}}", status_code=status.HTTP_204_NO_CONTENT,
                 summary=f"删除{self.model_name}",
                 description=f"根据ID删除{self.model_description}记录")
        def delete_item(item_id: int, db: Session = Depends(self.db_session)):
            db_item = db.query(self.model).filter(self.model.id == item_id).first()
            if not db_item:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail=f"{self.model.__name__} with id {item_id} not found"
                )
            try:
                db.delete(db_item)
                db.commit()
                return None
            except Exception as e:
                db.rollback()
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"Error deleting {self.model.__name__}: {str(e)}"
                )